package org.rabbit.mq.springbootrabbitconsumer;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @Author: zhs
 * @Date: 2021/6/15 14:48
 * @Description:
 */

/**
 * Consumer ACK机制：
 * 1.设置手动签收:acknowledge="manual"
 * 2.让监听器实现 ChannelAwareMessageListener 接口,并实现方法(也可向下面这样使用)
 * 3.如果消息处理成功，则调用 channel 的 basicAck() 签收
 * 4.如果消息处理失败，则调用 channel 的 basicNack() / basicReject() 拒绝签收，broker 重新发送消息
 */
//@Component
public class AckListener{

    @RabbitListener( queues = "boot_queue")
    public void listenerQueue(Message message, Channel channel) throws IOException {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();

        try {
            System.out.println("AckListener");
            //1.接收消息
            System.out.println(message);
            //2.处理业务逻辑
            System.out.println("===处理业务逻辑===");
            int i = 1/0; //假设发生异常，执行basicNack

            //3.手动签收
            // basicAck(long deliveryTag, boolean multiple)
            channel.basicAck(deliveryTag,true);
        } catch (IOException e) {
            //4.如果发生异常
            //拒绝签收
            //basicNack(long deliveryTag, boolean multiple, boolean requeue)
            // requeue: 重回队列,如果设置为true，则消息重新返回queue,broker会重新发送该消息给消费者
            channel.basicNack(deliveryTag,true,true);

            //处理单条,推荐使用上面的
            //channel.basicReject(deliveryTag,true);
        }
    }

}
